package com.mt.demo.socket;

import com.corundumstudio.socketio.AckRequest;
import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.annotation.OnConnect;
import com.corundumstudio.socketio.annotation.OnDisconnect;
import com.corundumstudio.socketio.annotation.OnEvent;
import com.mt.demo.domain.MtMember;
import com.mt.demo.manager.MeetingRoomManager;
import com.mt.demo.manager.MeetingUserManager;
import com.mt.demo.service.impl.HeartbeatService;
import com.mt.demo.service.impl.MeetingSyncService;
import com.mt.demo.service.impl.ScreenSharingService;
import com.mt.demo.service.impl.ZombieConnectionCleanupService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

@Component
public class SocketEventListener {

    @Autowired
    private SocketIOServer socketIOServer;

    @Autowired
    private MeetingRoomManager meetingRoomManager;

    @Autowired
    private MeetingUserManager meetingUserManager;

    @Autowired
    private HeartbeatService heartbeatService;

    @Autowired
    private ScreenSharingService screenSharingService;

    @Autowired
    private MeetingSyncService meetingSyncService;

    @Autowired
    private ZombieConnectionCleanupService zombieConnectionCleanupService;

    @OnConnect
    public void onConnect(SocketIOClient client) {
        String roomId = client.getHandshakeData().getSingleUrlParam("roomId");
        String userId = client.getHandshakeData().getSingleUrlParam("userId");

        // 将客户端添加到房间
        meetingRoomManager.addClientToRoom(roomId, client);

        // 获取用户信息并添加到在线用户列表
        MtMember member = meetingRoomManager.getUserInfo(userId);
        if (member != null) {
            meetingUserManager.addOnlineUser(roomId, member);
        }

        // 通知房间其他用户有新用户加入
        meetingRoomManager.getRoomClients(roomId).forEach(roomClient -> {
            if (!roomClient.getSessionId().equals(client.getSessionId())) {
                roomClient.sendEvent("userJoined", member);
            }
        });

        // 同步房间状态
        meetingSyncService.syncRoomStatus(roomId);
    }

    @OnDisconnect
    public void onDisconnect(SocketIOClient client) {
        String roomId = client.getHandshakeData().getSingleUrlParam("roomId");
        String userId = client.getHandshakeData().getSingleUrlParam("userId");

        // 清理屏幕共享状态
        screenSharingService.cleanupUserScreenSharing(roomId, userId);

        // 从房间移除客户端
        meetingRoomManager.removeClientFromRoom(roomId, client);

        // 从在线用户列表移除
        meetingUserManager.removeOnlineUser(roomId, userId);

        // 通知房间其他用户
        meetingRoomManager.getRoomClients(roomId).forEach(roomClient -> {
            roomClient.sendEvent("userLeft", userId);
        });
    }

    @OnEvent("ping")
    public void onPing(SocketIOClient client) {
        heartbeatService.handleHeartbeat(client);
    }

    @OnEvent("startScreenShare")
    public void onStartScreenShare(SocketIOClient client) {
        String roomId = client.getHandshakeData().getSingleUrlParam("roomId");
        String userId = client.getHandshakeData().getSingleUrlParam("userId");

        boolean success = screenSharingService.startScreenSharing(roomId, userId, client);
        client.sendEvent("screenShareResponse", success);
    }

    @OnEvent("stopScreenShare")
    public void onStopScreenShare(SocketIOClient client) {
        String roomId = client.getHandshakeData().getSingleUrlParam("roomId");
        String userId = client.getHandshakeData().getSingleUrlParam("userId");

        screenSharingService.stopScreenSharing(roomId, userId, client);
    }

    @OnEvent("requestMeetingSync")
    public void onRequestMeetingSync(SocketIOClient client) {
        String roomId = client.getHandshakeData().getSingleUrlParam("roomId");
        meetingSyncService.syncRoomStatus(roomId);
    }

    @OnEvent("confirmMeetingInfo")
    public void onConfirmMeetingInfo(SocketIOClient client) {
        String clientId = client.getSessionId().toString();
        zombieConnectionCleanupService.resetErrorCount(clientId);
    }

    @OnEvent("joinMeetingRoom")
    public void onJoinMeetingRoom(SocketIOClient client, Map<String, Object> data) {
        String roomId = (String) data.get("roomId");
        String userId = (String) data.get("userId");
        
        // 更新客户端参数
        client.getHandshakeData().getUrlParams().put("roomId", Arrays.asList(roomId));
        client.getHandshakeData().getUrlParams().put("userId", Arrays.asList(userId));
        
        // 触发连接处理逻辑
        onConnect(client);
        
        // 发送加入成功响应
        Map<String, Object> joinRoomSuccessResponse = new HashMap<>();
        joinRoomSuccessResponse.put("roomId", roomId);
        joinRoomSuccessResponse.put("userId", userId);
        joinRoomSuccessResponse.put("message", "成功加入会议房间");

        client.sendEvent("joinRoomSuccess", joinRoomSuccessResponse);
    }

    @OnEvent("error")
    public void onError(SocketIOClient client) {
        zombieConnectionCleanupService.handleConnectionError(client);
    }

    // WebRTC 信令事件处理
    @OnEvent("offer")
    public void onOffer(SocketIOClient client, Object data, AckRequest ackRequest) {
        String roomId = client.getHandshakeData().getSingleUrlParam("roomId");
        String userId = client.getHandshakeData().getSingleUrlParam("userId");

        // 转发 offer 给房间内其他用户
        meetingRoomManager.getRoomClients(roomId).forEach(roomClient -> {
            if (!roomClient.getSessionId().equals(client.getSessionId())) {
                roomClient.sendEvent("offer", data);
            }
        });
    }

    @OnEvent("answer")
    public void onAnswer(SocketIOClient client, Object data, AckRequest ackRequest) {
        String roomId = client.getHandshakeData().getSingleUrlParam("roomId");
        String userId = client.getHandshakeData().getSingleUrlParam("userId");

        // 转发 answer 给房间内其他用户
        meetingRoomManager.getRoomClients(roomId).forEach(roomClient -> {
            if (!roomClient.getSessionId().equals(client.getSessionId())) {
                roomClient.sendEvent("answer", data);
            }
        });
    }

    @OnEvent("candidate")
    public void onCandidate(SocketIOClient client, Object data, AckRequest ackRequest) {
        String roomId = client.getHandshakeData().getSingleUrlParam("roomId");
        String userId = client.getHandshakeData().getSingleUrlParam("userId");

        // 转发 ICE candidate 给房间内其他用户
        meetingRoomManager.getRoomClients(roomId).forEach(roomClient -> {
            if (!roomClient.getSessionId().equals(client.getSessionId())) {
                roomClient.sendEvent("candidate", data);
            }
        });
    }
}
